/****************************************************
          File Name:17-5.cpp
          Author: Abby Cin
          Mail: abbytsing@gmail.com
          Created Time: Tue Jan 20 17:20:08 2015
*****************************************************/

#include<iostream>
#include<fstream>
#include<cstdlib>

using namespace std;

class Content
{
    private:
        string m_name;
        bool tof;   // true or false
    public:
        Content *next;
        Content() : next(nullptr), tof(true) {};
        bool istrue() { return tof; }
        void tofalse() { tof = false; }
        void push(string name);
        string pop();
};


void Content::push(string name)
{
    m_name = name;
}

string Content::pop()
{
    return m_name;
}

int main(int argc, char *argv[])
{
    Content *head1 = new Content;
    Content *head2 = new Content;
    string name1, name2;
    
    ifstream if_1;
    ifstream if_2;
    ofstream of;

    try
    {
        if_1.open(argv[1]);
        if_2.open(argv[2]);
        of.open(argv[3]);
    }
    catch(ios_base::failure &bad)
    {
        cout << bad.what() << endl;
        delete head1;
        delete head2;
        exit(EXIT_FAILURE);
    }

    Content *add1 = new Content;
    add1 = head1;
    while(getline(if_1, name1))
    {
        Content *tmp1 = new Content;
        tmp1->push(name1);
        tmp1->next = nullptr;
        add1->next = tmp1;
        add1 = add1->next;
    }
    Content *add2 = new Content;
    add2 = head2;
    while(getline(if_2, name2))
    {
        Content *tmp = new Content;
        tmp->push(name2);
        tmp->next = nullptr;
        add2->next = tmp;
        add2 = add2->next;
    }

    cout << "friends of Mat\n";
    add1 = head1;
    while(add1 != nullptr)
    {
        cout << add1->pop() << endl;
        add1 = add1->next;
    }
    cout << "friends of Pat\n";
    add2 = head2;
    while(add2 != nullptr)
    {
        cout << add2->pop() << endl;
        add2 = add2->next;
    }
    // merge two files to argv[3]: matpat.dat

    add1 = head1;
    while(add1 != nullptr)
    {
        add2 = head2;
        while(add2 != nullptr)
        {
            if(add1->pop() == add2->pop())
                    add2->tofalse();
            add2 = add2->next;
        }   
        add1 = add1->next;
    }

    add1 = head1;
    while(add1 != nullptr)
    {
        of << add1->pop() << endl;
        add1 = add1->next;
    }
    add2 = head2;
    while(add2 != nullptr)
    {
        if(add2->istrue())
            of << add2->pop() << endl;
        add2 = add2->next;
    }

    // destory list
    while(head1 != nullptr)
    {
        add1 = head1;
        head1 = head1->next;
        delete add1;
        cout << "--\e[36m deleting list 1 \e[0m---" << endl;
    }

    while(head2 != nullptr)
    {
        add2 = head2;
        head2 = head2->next;
        delete add2;
        cout << "--\e[35m deleting list 2 \e[0m---" << endl;
    }

    if_1.close();
    if_2.close();
    of.close();

    delete head1;
    delete head2;
    delete add1;
    delete add2;

    return 0;
}
